<template>
  <div class="ai absolute inset-0 flex flex-col"
       @keyup.enter="(e) => onSend(text,e)">
    <BPageHeader icon="ai|png"
                 name="MSPbots AI"
                 :isView="false" />
    <ZContainer :noPadding="true"
                :noBorder="true"
                class="ai-container flex flex-col items-center relative">

      <div class="ai-body overflow-auto"
           ref="scroll-container">
        <MediaBox v-for="(item,index) in $store.state.ai.contents"
                  :key="index"
                  :item="item" />
      </div>

      <div class="ai-footer absolute bottom-0 w-full center-center">
        <div class="ai-footer__waiting"
             v-if="$store.state.ai.loading">
          <span></span>
          <span></span>
          <span></span>
        </div>

        <div class="ai-footer__body h-full flex items-center">
          <el-input v-model="text"
                    placeholder="Send a message..."
                    type="textarea"
                    autofocus
                    autosize></el-input>
          <ZIcon icon="cuifont icon_send"
                 class="cursor-pointer"
                 :size="20"
                 :disabled="$store.state.ai.loading"
                 @click="(e)=>onSend(text,e)" />
        </div>
      </div>
    </ZContainer>
  </div>
</template>

<script>
import { set } from 'lodash'
import BPageHeader from '@/components/storybook/b-page-header/index.vue'
import ZContainer from '@/components/storybook/z-container'
import ZIcon from '@/components/storybook/z-icon'
import MediaBox from './components/media-box.vue'
import { chatSQL, createQuery, fetchQuery } from '@/api/new'


export default {
  name: 'Ai',
  components: {
    BPageHeader,
    ZContainer,
    ZIcon,
    MediaBox,
  },
  data () {
    return {
      text: undefined,
    }
  },
  computed: {
    contentsLen () {
      return this.$store.state.ai.contents.length
    }
  },
  watch: {
    contentsLen (value) {
      this.$nextTick(() => {
        const el = this.$refs['scroll-container']
        el.scrollTop = el.scrollHeight
      })
    }
  },

  methods: {

    async getQueryData (content) {
      const { options } = this.$store.getters.dataset

      const { data: response1 } = await createQuery({
        tenantCode: Cookies.get('tenant_code'),
        type: 1,
        datasetId: options.id,
        content,
        dimensions: []
      })

      if (response1.code !== 0) {
        throw response1.msg
      }
      const { data: response2 } = await fetchQuery({
        showQuery: false,
        showSql: true,
        queryId: response1.data.id
      })
      if (response2.code !== 0) {
        throw response2.msg
      }
      return {
        query: response1.data || {},
        dataset: response2.data || []
      }
    },
    async getChatData (text) {
      const params = {
        userId: this.$store.state.user.id,
        tenantCode: this.$store.state.user.tenantCode,
        taskInfo: 'sql_view',
        selectDataset: 0,
        text
      }
      if (this.$store.getters.dataset) {
        const { options } = this.$store.getters.dataset
        set(params, 'selectDataset', 1)
        set(params, 'tableInfo', [{
          table: `dataset_${options.id}`,
          info: options.dataset.length ? Object.keys(options.dataset[0]) : []
        }])
      }
      const { data: response } = await chatSQL(params)
      return response.data || {}
    },

    async onSend (text, e) {
      if(e.shiftKey || !text){
        return
      }
      try {
        this.$store.state.ai.loading = true
        this.text = undefined
        this.$store.commit('SET_CONTENT',
          {
            type: 'USER',
            name: "Message",
            options: {
              message: text
            }
          },
        )
        const data = await this.getChatData(text)
        if (data.name === 'Query') {
          const { query, dataset } = await this.getQueryData(data.options.sql.replace('dataset_', 'dataset-'))
          set(data, 'query', true)
          set(data, 'options.dataset', dataset)
          set(data, 'options.query', query)
        }
        this.$store.commit('SET_CONTENT',
          {
            type: 'GPT',
            ...data
          },
        )
      } catch (message) {
        this.$store.commit('SET_CONTENT',
          {
            type: 'GPT',
            name: "Message",
            options: {
              message:'Failed to create a widget based on the current description. Please update the description'
            }
          },
        )
      } finally {
        this.$store.state.ai.loading = false
      }
    },
  }
}
</script>



<style lang="scss" scoped>
@keyframes blink {
  50% {
    opacity: 1;
  }
}
.media-action {
  margin-top: 10px;
}
.ai {
  &-body {
    width: 100%;
    padding-left: 20%;
    padding-right: 20%;
    padding-top: 16px;
    height: calc(100% - 72px);
    padding-bottom: 32px;
  }
  &-footer {
    padding: 18px 0;
    background: #ffffff;
    box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.14);
    opacity: 1;
    border: 1px solid rgba(0, 0, 0, 0.08);
    &__waiting {
      position: absolute;
      top: -25px;
      left: 20%;
      span {
        display: inline-block;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background-color: #909399;
        margin-right: 4px;
        opacity: 0.4;
        &:nth-of-type(1) {
          animation: 1s blink infinite 0.33333s;
        }
        &:nth-of-type(2) {
          animation: 1s blink infinite 0.66666s;
        }
        &:nth-of-type(3) {
          animation: 1s blink infinite 0.99999s;
        }
      }
    }
    &__body {
      width: 60%;
      .el-textarea {
        ::v-deep .el-textarea__inner {
          min-height: 40px;
          background: rgba(255, 255, 255, 0.7);
          border-radius: 4px;
          border: 1px solid;
          border-image: linear-gradient(
              180deg,
              rgba(0, 0, 0, 0.06),
              rgba(0, 0, 0, 0.16)
            )
            1 1;
        }
      }
      .z-icon {
        margin-left: 8px;
      }
    }
  }
}
</style>